/**********************************************************

file:  Camera_LS_Y201.c

Author:	  albert

 **********************************************************/

#include "Camera_LS_Y201.h"
#include "atmega128_usart.h"
#include "Xbee.h"
#include "Timer.h"

unsigned char camera_usart_num = 1;
unsigned int read_bytes = 160; //Notes: read bytes takes 16 bits place, here only Lower byte need to be set
unsigned char jpeg_content[500];

volatile unsigned char pass_check_flag = 0;
volatile unsigned char pass_count = 1;
volatile unsigned char camera_temp = 0;
volatile unsigned int file_size = 0; //XH XL
volatile unsigned int read_address = 0;
volatile unsigned int read_end = 0;
volatile unsigned int jpeg_content_count;





struct Camera_protocol
{
  unsigned char reset[4];
  unsigned char reset_ret[4];
  unsigned char take_pic[5];
  unsigned char take_pic_ret[5];
  unsigned char rd_jpeg_size[5];
  unsigned char rd_jpeg_size_ret[7];
  unsigned char compres_ratio[9];
  unsigned char compres_ratio_ret[5];
  unsigned char img_size[9];
  unsigned char img_size_ret[5];
  unsigned char stop_pic[5];
  unsigned char stop_pic_ret[5];

} cam_protocol = 
{
  {
    0x56, 0x00, 0x26, 0x00
  }
  , 
  {
    0x76, 0x00, 0x26, 0x00
  }
  , 
  {
    0x56, 0x00, 0x36, 0x01, 0x00
  }
  , 
  {
    0x76, 0x00, 0x36, 0x00, 0x00
  }
  , 
  {
    0x56, 0x00, 0x34, 0x01, 0x00
  }
  , 
  {
    0x76, 0x00, 0x34, 0x00, 0x04, 0x00, 0x00
  }
  , 
  {
    0x56, 0x00, 0x31, 0x05, 0x01, 0x01, 0x12, 0x04, 0xFF
  }
  , 
  {
    0x76, 0x00, 0x31, 0x00, 0x00
  }
  , 
  {
    0x56, 0x00, 0x31, 0x05, 0x04, 0x01, 0x00, 0x19, 0x22
  }
  , 
  {
    0x76, 0x00, 0x31, 0x00, 0x00
  }
  , 
  {
    0x56, 0x00, 0x36, 0x01, 0x03
  }
  , 
  {
    0x76, 0x00, 0x36, 0x00, 0x00
  }
};

/**************************************************************************
 *Check the number of bytes return from Camera                            *
 **************************************************************************/

unsigned char camera_return_value_chk(unsigned char ret_bytes)
{

  if (usart_mode == 0)
  {
    while (usart1_count != ret_bytes)
    {
      USART_Receive(camera_usart_num);
      if (usart1_count == 1 && timer_tick == 1)
      //if (usart1_count == 1)
        return  - 1;
    }
    return 1;

  }
  else
  {
    if (timer_enable == 1)
      Timer1_TwoSecond();
    while (usart1_count != ret_bytes && timer_tick == 0)
    //while (usart1_count != ret_bytes)
      ;
    if (usart1_count == 0 && timer_tick == 1)
    //if (usart1_count == 0 )
      return  - 1;
    else
      return 1;
  }

}

/**************************************************************************
 * stop taking image                                                      *
 *                                                                        *
 **************************************************************************/

unsigned char Camera_Stop_taking_pic(void)
{
  usart1_count = 0;
  USART_BYTES_Transmit(camera_usart_num, cam_protocol.stop_pic, sizeof(cam_protocol.stop_pic));
  if (camera_return_value_chk(sizeof(cam_protocol.stop_pic_ret)) == 1)
  {
    for (camera_temp = 0; camera_temp < sizeof(cam_protocol.stop_pic_ret); camera_temp++)
    {
      if (usart1_rec_buff[camera_temp] != cam_protocol.stop_pic_ret[camera_temp])
        return  - 1;
    }
    return 1;
  }
  return  - 1;

}


/**************************************************************************
 * Jpeg image compression ratio                                           *
 *  //For now, use 0xff c_ratio                                           *
 **************************************************************************/

unsigned char Camera_Compression_ratio(void)
{
  usart1_count = 0;
  USART_BYTES_Transmit(camera_usart_num, cam_protocol.compres_ratio, sizeof(cam_protocol.compres_ratio));
  if (camera_return_value_chk(sizeof(cam_protocol.compres_ratio_ret)) == 1)
  {
    for (camera_temp = 0; camera_temp < sizeof(cam_protocol.compres_ratio_ret); camera_temp++)
    {
      if (usart1_rec_buff[camera_temp] != cam_protocol.compres_ratio_ret[camera_temp])
        return  - 1;
    }
    return 1;
  }
  return  - 1;

}

/**************************************************************************
 * Set Image size                                                         *
 **************************************************************************/

unsigned char Camera_image_size(void)
{
  usart1_count = 0;
  USART_BYTES_Transmit(camera_usart_num, cam_protocol.img_size, sizeof(cam_protocol.img_size));
  if (camera_return_value_chk(sizeof(cam_protocol.img_size_ret)) == 1)
  {
    for (camera_temp = 0; camera_temp < sizeof(cam_protocol.img_size_ret); camera_temp++)
    {
      if (usart1_rec_buff[camera_temp] != cam_protocol.img_size_ret[camera_temp])
        return  - 1;
    }
    return 1;
  }
  return  - 1;

}

/**************************************************************************
 * Take a picture                                                          *
 **************************************************************************/

unsigned char Camera_takePicture(void)
{
  usart1_count = 0;
  USART_BYTES_Transmit(camera_usart_num, cam_protocol.take_pic, sizeof(cam_protocol.take_pic));
  if (camera_return_value_chk(sizeof(cam_protocol.take_pic_ret)) == 1)
  {
    for (camera_temp = 0; camera_temp < sizeof(cam_protocol.take_pic_ret); camera_temp++)
    {
      if (usart1_rec_buff[camera_temp] != cam_protocol.take_pic_ret[camera_temp])
        return  - 1;
    }
    return 1;
  }
  return  - 1;

}

/**************************************************************************
 *Read Jpeg image size                                                    *
 **************************************************************************/

unsigned char Camera_jpeg_file_size(void)
{
  usart1_count = 0;
  file_size = 0;
  USART_BYTES_Transmit(camera_usart_num, cam_protocol.rd_jpeg_size, sizeof(cam_protocol.rd_jpeg_size));
  if (camera_return_value_chk(sizeof(cam_protocol.rd_jpeg_size_ret) + 2) == 1)
  {
    for (camera_temp = 0; camera_temp < sizeof(cam_protocol.rd_jpeg_size_ret); camera_temp++)
    {
      if (usart1_rec_buff[camera_temp] != cam_protocol.rd_jpeg_size_ret[camera_temp])
        return  - 1;
    }
    unsigned char file_size_hex[2];
    file_size_hex[0] = usart1_rec_buff[camera_temp];
    file_size_hex[1] = usart1_rec_buff[++camera_temp];
    file_size = file_size_hex[0];
    file_size = (file_size << 8) + file_size_hex[1];

    return 1;
  }
  return  - 1;

}

/**************************************************************************
 *                                                                        *
 **************************************************************************/

unsigned char Camera_Read_jpeg(void)
{

  unsigned char cmd[16] = 
  {
    0x56, 0x00, 0x32, 0x0C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,  //starting address 0x0000
    0x00, 0x00, 0x00, 0x00, 0x00, 0x0A
  };
  cmd[13] = read_bytes;
  jpeg_content_count = 0;
  read_address = 0;
  while (jpeg_content_count < file_size)
  {
    if (usart1_count != 0)
      usart1_count = 0;
    cmd[8] = (read_address >> 8);
    cmd[9] = read_address;

    USART_BYTES_Transmit(camera_usart_num, cmd, sizeof(cmd));
    if (camera_return_value_chk(read_bytes + 10) != 1)
    {
      return  - 1;
    }
    else
    {
      for (unsigned char m = 5; m < (read_bytes + 5) && jpeg_content_count < file_size; m++)
      {
        //instead of saving local, directly transmit to xbee
        USART_Transmit(xbee_usart_num, usart1_rec_buff[m]);
        //jpeg_content[jpeg_content_count]=usart1_rec_buff[m];
        jpeg_content_count++;
      }
      read_address += read_bytes;
    }
  }
  return 1;
}


/**************************************************************************
 * Reset Camera                                                           *
 **************************************************************************/



unsigned char Camera_Reset(void)
{

  unsigned char init_end[15] = 
  {
    0x36, 0x32, 0x35, 0x0D, 0x0A, 0x49, 0x6E, 0x69, 0x74, 0x20, 0x65, 0x6E, 0x64, 0x0D, 0x0A
  };
  usart1_count = 0;
  USART_BYTES_Transmit(camera_usart_num, cam_protocol.reset, sizeof(cam_protocol.reset));
  if (camera_return_value_chk(71) == 1)
  {

    for (unsigned char i = 56; i < 71; i++)
    {
      if (init_end[i - 56] != usart1_rec_buff[i])
        return  - 1;

    }
    _delay_ms(3500);
    return 1;

  }
  else
    return  - 1;
}
